#ifndef LEXICALUNIT_H_INCLUDED_XAIRY
#define LEXICALUNIT_H_INCLUDED_XAIRY

#include <string>
using std::string;

class LexicalUnit
{
public:
	enum LexicalUnitType
	{
		/* Operators */
    /*
      Note that these operators have no meaning for the parser,
      it's up to the user to interpret each operators.
    */
    SAC_OPERATOR_COMMA = 0,			/* , */
    SAC_OPERATOR_PLUS,			/* + */
    SAC_OPERATOR_MINUS,			/* - */
    SAC_OPERATOR_MULTIPLY,		/* * */
    SAC_OPERATOR_SLASH,			/* / */
    SAC_OPERATOR_MOD,			/* % */
    SAC_OPERATOR_EXP,			/* ^ */
    SAC_OPERATOR_LT,			/* < */
    SAC_OPERATOR_GT,			/* > */
    SAC_OPERATOR_LE,			/* <= */
    SAC_OPERATOR_GE,			/* >= */
    SAC_OPERATOR_TILDE,			/* ~ */

    SAC_INHERIT,		/* identifier inherit */
    /* Integers and reals numbers */
    SAC_INTEGER,
    SAC_REAL,
    /* Relative lengths */
    SAC_EM,
    SAC_EX,
    SAC_PIXEL,
    /* Absolute lengths */
    SAC_INCH,
    SAC_CENTIMETER,
    SAC_MILLIMETER,
    SAC_POINT,
    SAC_PICA,
    /* Percentages */
    SAC_PERCENTAGE,
    /* URI */
    SAC_URI,
    /* Counters */
    SAC_COUNTER_FUNCTION,
    SAC_COUNTERS_FUNCTION,
    /* RGB Colors */
    SAC_RGBCOLOR,		/* rgb(0, 0, 0) and #000 */
    /* Angles */
    SAC_DEGREE,
    SAC_GRADIAN,
    SAC_RADIAN,
    /* Times */
    SAC_MILLISECOND,
    SAC_SECOND,
    /* Frequencies */
    SAC_HERTZ,
    SAC_KILOHERTZ,
    /* Misc */
    SAC_IDENT,			/* any ident except inherit ! */
    SAC_STRING_VALUE,
    SAC_ATTR,		        /* attribute */
    SAC_RECT_FUNCTION,		/* rect shape function */
    SAC_UNICODERANGE,

    /* sub expressions */
    SAC_SUB_EXPRESSION,		/* (a) (a + b) (normal/none) */

    /* Unknown values */
    SAC_FUNCTION,		/* unknown function */
    SAC_DIMENSION,		/* unknown dimension */

    SAC_UNKNOWN
	};

public:
	virtual ~LexicalUnit(){}

	virtual LexicalUnitType getLexicalUnitType()const = 0;
	virtual LexicalUnit* getNextLexicalUnit()const = 0;
	virtual LexicalUnit* getPreviousLexicalUnit()const = 0;

	/**
     * Returns the integer value.
     * @see #SAC_INTEGER
     */
	virtual int getIntegerValue()const = 0;

	/**
     * Returns the float value.
     * <p>If the type of <code>LexicalUnit</code> is one of SAC_DEGREE,
     * SAC_GRADIAN, SAC_RADIAN, SAC_MILLISECOND, SAC_SECOND, SAC_HERTZ
     * or SAC_KILOHERTZ, the value can never be negative.</p>
     *
     * @see #SAC_REAL
     * @see #SAC_DIMENSION
     * @see #SAC_EM
     * @see #SAC_EX
     * @see #SAC_PIXEL
     * @see #SAC_INCH
     * @see #SAC_CENTIMETER
     * @see #SAC_MILLIMETER
     * @see #SAC_POINT
     * @see #SAC_PICA
     * @see #SAC_PERCENTAGE
     * @see #SAC_DEGREE
     * @see #SAC_GRADIAN
     * @see #SAC_RADIAN
     * @see #SAC_MILLISECOND
     * @see #SAC_SECOND
     * @see #SAC_HERTZ
     * @see #SAC_KILOHERTZ
     */
	virtual float getFloatValue()const = 0;

	/**
     * Returns the string representation of the unit.
     * <p>if this lexical unit represents a float, the dimension is an empty
     * string.</p>
     * @see #SAC_REAL
     * @see #SAC_DIMENSION
     * @see #SAC_EM
     * @see #SAC_EX
     * @see #SAC_PIXEL
     * @see #SAC_INCH
     * @see #SAC_CENTIMETER
     * @see #SAC_MILLIMETER
     * @see #SAC_POINT
     * @see #SAC_PICA
     * @see #SAC_PERCENTAGE
     * @see #SAC_DEGREE
     * @see #SAC_GRADIAN
     * @see #SAC_RADIAN
     * @see #SAC_MILLISECOND
     * @see #SAC_SECOND
     * @see #SAC_HERTZ
     * @see #SAC_KILOHERTZ
     */
	virtual string getDimensionUnitText()const = 0;

	/**
     * Returns the name of the function.
     * @see #SAC_COUNTER_FUNCTION
     * @see #SAC_COUNTERS_FUNCTION
     * @see #SAC_RECT_FUNCTION
     * @see #SAC_FUNCTION
     * @see #SAC_RGBCOLOR
     */
     virtual string getFunctionName()const = 0;

     /**
     * The function parameters including operators (like the comma).
     * <code>#000</code> is converted to <code>rgb(0, 0, 0)</code>
     * can return <code>null</code> if <code>SAC_FUNCTION</code>.
     * @see #SAC_COUNTER_FUNCTION
     * @see #SAC_COUNTERS_FUNCTION
     * @see #SAC_RECT_FUNCTION
     * @see #SAC_FUNCTION
     * @see #SAC_RGBCOLOR
     */
	virtual LexicalUnit* getParameters()const = 0;

	/**
     * Returns the string value.
     * <p>If the type is <code>SAC_URI</code>, the return value doesn't contain
     * <code>uri(....)</code> or quotes.
     * <p>If the type is <code>SAC_ATTR</code>, the return value doesn't contain
     * <code>attr(....)</code>.
     *
     * @see #SAC_URI
     * @see #SAC_ATTR
     * @see #SAC_IDENT
     * @see #SAC_STRING_VALUE
     * @see #SAC_UNICODERANGE @@TO BE DEFINED
     */
	virtual string getStringValue()const = 0;

	/**
     * Returns a list of values inside the sub expression.
     * @see #SAC_SUB_EXPRESSION
     */
    virtual LexicalUnit* getSubValues()const = 0;

    virtual const string* toString()const = 0;
};


#endif // LEXICALUNIT_H_INCLUDED_XAIRY
